<template>
    <div class="home-container">
        <tool-bar ref="toolBarRef" @handleEvents="handleMarkdownEvents"
                  @handle-client-events="handleClientEvents"></tool-bar>
        <div class="home-content">
            <div class="left-nav">
                <nav class="nav-wrap">
                    <div class="nav-item nav-file" :class="{'focus': isShowFileControl}" @click="openFileControl">
                        <i class="iconfont icon-file"></i>
                    </div>
                    <!-- <div class="nav-item nav-branch" :class="{'focus': isShowChangeControl}" @click="openChangeControl">
                        <div class="iconfont icon-change"></div>
                    </div> -->
                    <div class="nav-item nav-item-bottom nav-setting" @click="openSetModal">
                        <div class="iconfont icon-setting"></div>
                    </div>
                </nav>
                <div class="control-wrap" v-show="isShowFileControl || isShowChangeControl">
                    <div class="control-file" v-show="isShowFileControl">
                        <file-tree ref="fileTreeRef" @selected-file="handleSelectedFile"
                                   @crate-new-file="handleCreateNewFile"></file-tree>
                    </div>
                    <div class="control-change" v-show="isShowChangeControl"></div>
                </div>
            </div>
            <div class="left-word">
                <code-mirror-editor ref="codeMirrorEditorRef" @editorChange="handleChangeValue"
                                    @scroll="handleEditorScroll"></code-mirror-editor>
            </div>
            <div class="right-view" ref="rightViewRef" v-show="viewDevice !== 'none'" @scroll="handleRenderScroll">
                <show-down ref="showDownRef" :text="markdownValue"></show-down>
            </div>
        </div>

        <div class="home-foot-version">v {{ version }}</div>

        <tool-copy :text="markdownValue"></tool-copy>
    </div>
</template>

<script>
import {ElMessage} from 'element-plus';
import {mapState} from "pinia";
import {onMounted, onUnmounted} from 'vue';
import FileTree from "../../components/FileTree.vue";
import ToolBar from "../../components/ToolBar.vue";
import ToolCopy from "../../components/ToolCopy.vue";
import CodeMirrorEditor from "../../components/CodeMirrorEditor.vue";
import ShowDown from "../../components/ShowDown.vue";
import packageJson from "../../../package.json"

import {useSystemStore} from "../../store/index.js";
import {useFileStore} from "../../store/fileStore.js";

export default {
    name: "Home",
    components: {
        FileTree,
        ToolBar,
        ToolCopy,
        CodeMirrorEditor,
        ShowDown
    },
    data() {
        return {
            isShowFileControl: false,
            isShowChangeControl: false,
            jsonEditor: "",
            markdownValue: "",
            isSyncing: false,  // 是否同步滚动中
            scrollRatio: 1,
            version: packageJson.version,
            trayEventUnlisten: null,
            resizeObserver: null  // 用于监听左侧导航宽度变化
        };
    },
    computed: {
        ...mapState(useSystemStore, ['viewDevice']),
        ...mapState(useFileStore, ['fileText'])
    },
    async mounted() {
        // 监听系统托盘的新建文件事件
        if (window.__TAURI__) {
            const { listen } = window.__TAURI__.event;
            this.trayEventUnlisten = await listen('new-file', () => {
                this.handleTrayNewFile();
            });
        }
        
        // 监听左侧导航宽度变化
        this.setupResizeObserver();
    },
    unmounted() {
        // 清理事件监听器
        if (this.trayEventUnlisten) {
            this.trayEventUnlisten();
        }
        
        // 清理ResizeObserver
        if (this.resizeObserver) {
            this.resizeObserver.disconnect();
        }
    },
    methods: {
        openFileControl() {
            this.isShowFileControl = !this.isShowFileControl;
            this.isShowChangeControl = false;
            // 导航栏变化后刷新编辑器布局
            this.handleNavResize();
        },
        openChangeControl() {
            this.isShowChangeControl = !this.isShowChangeControl;
            this.isShowFileControl = false;
            // 导航栏变化后刷新编辑器布局
            this.handleNavResize();
        },
        openSetModal() {
            this.$refs.toolBarRef.isOpenSetting = true;
        },
        handleChangeValue(val) {
            this.markdownValue = val;
            this.$nextTick(() => {
                this.getScrollRatio()
            })
        },
        /** 文档内容传入编辑器中 */
        handleSelectedFile() {
            this.$refs.codeMirrorEditorRef.handleSetValue(this.fileText);
        },
        /** 操作文档事件方法 */
        handleMarkdownEvents(eventType, valueObj) {
            const codeMirrorEditorRef = this.$refs.codeMirrorEditorRef;
            switch (eventType) {
                case 'bold':
                    codeMirrorEditorRef.handleApplyBold();
                    break;
                case 'del':
                    codeMirrorEditorRef.handleApplyDel();
                    break;
                case 'underline':
                    codeMirrorEditorRef.handleApplyUnderline();
                    break;
                case 'italic':
                    codeMirrorEditorRef.handleApplyItalic();
                    break;
                case 'code':
                    codeMirrorEditorRef.handleApplyCode();
                    break;
                case 'line-sign':
                    codeMirrorEditorRef.handleApplyLineSign();
                    break;
                case 'link':
                    codeMirrorEditorRef.handleInsertLink();
                    break;
                case 'table':
                    codeMirrorEditorRef.handleInsertTable();
                    break;
                case 'image':
                    codeMirrorEditorRef.handleInsertImage(valueObj);
                    break;
                case 'ordered-list':
                    codeMirrorEditorRef.handleInsertOrderedList();
                    break;
                case 'unordered-list':
                    codeMirrorEditorRef.handleInsertUnorderedList();
                    break;
                case 'one-title':
                    codeMirrorEditorRef.handleInsertHeading(1);
                    break;
                case 'two-title':
                    codeMirrorEditorRef.handleInsertHeading(2);
                    break;
                case 'there-title':
                    codeMirrorEditorRef.handleInsertHeading(3);
                    break;
                case 'four-title':
                    codeMirrorEditorRef.handleInsertHeading(4);
                    break;
                case 'five-title':
                    codeMirrorEditorRef.handleInsertHeading(4);
                    break;

                case 'reset':
                    codeMirrorEditorRef.handleReset();
                    break;
                case 'findPrev':
                    codeMirrorEditorRef.handleFindPrev(valueObj);
                    break;
                case 'findNext':
                    codeMirrorEditorRef.handleFindNext(valueObj);
                    break;
                case 'replace':
                    codeMirrorEditorRef.handleReplace(valueObj);
                    break;
                case 'replaceAll':
                    codeMirrorEditorRef.handleReplaceAll(valueObj);
                    break;
                case 'insertDownFooter':
                    codeMirrorEditorRef.handleInsertDownFooter(valueObj);
                    break;
                default:
                    ElMessage({
                        message: '你在尝试一个未知的功能!',
                        type: 'warning',
                    })
            }
        },
        /**
         * 操作客户端事件方法
         * @param {string} eventType 事件类型
         * @param eventData 事件数据
         * */
        handleClientEvents(eventType, eventData) {
            switch (eventType) {
                case 'selectFile':
                    this.$refs.fileTreeRef.handleNodeClick({
                        isFile: true,
                        path: eventData.address
                    });
                    break;
                case 'saveFile':
                    this.$refs.codeMirrorEditorRef.handleSaveFile();
                    break;
                default:
                    ElMessage({
                        message: '你在尝试一个未知的功能!',
                        type: 'warning',
                    })
            }
        },
        /** 处理系统托盘的新建文件事件 */
        handleTrayNewFile() {
            // 确保文件控制面板是打开的
            this.isShowFileControl = true;
            this.isShowChangeControl = false;
            
            // 触发新建文件对话框
            this.$refs.toolBarRef.isOpenCreateFile = true;
            this.$refs.toolBarRef.createNewFilePath = '';
            
            ElMessage({
                message: '正在创建新文件...',
                type: 'success',
            });
        },
        handleCreateNewFile({path}) {
            this.$refs.toolBarRef.isOpenCreateFile = true;
            this.$refs.toolBarRef.createNewFilePath = path;
        },
        handleEditorScroll(val) {
            if (this.isSyncing) return;
            this.isSyncing = true;
            this.$refs.rightViewRef.scrollTop = val.top / this.scrollRatio;
            this.isSyncing = false;
        },
        handleRenderScroll({target: {scrollTop}}) {
            if (this.isSyncing) return;
            this.isSyncing = true;
            this.$refs.codeMirrorEditorRef.handleScroll(scrollTop * this.scrollRatio);
            this.isSyncing = false;
        },
        /** 计算滚动比例 */
        getScrollRatio() {
            // 获取编辑器区域高度
            let editorDOM = document.getElementsByClassName('CodeMirror-sizer');
            let editorHeight = editorDOM[0].clientHeight;
            // 获取渲染区域高度
            let renderDOM = document.getElementById('blueNoteBox');
            let renderHeight = renderDOM.clientHeight;

            this.scrollRatio = editorHeight / renderHeight;
        },
        
        /** 设置尺寸变化监听器 */
        setupResizeObserver() {
            // 等待DOM渲染完成
            this.$nextTick(() => {
                const leftNavElement = this.$el.querySelector('.left-nav');
                if (leftNavElement && window.ResizeObserver) {
                    this.resizeObserver = new ResizeObserver((entries) => {
                        // 防抖处理，避免频繁调用
                        clearTimeout(this.resizeTimer);
                        this.resizeTimer = setTimeout(() => {
                            this.handleNavResize();
                        }, 100);
                    });
                    
                    this.resizeObserver.observe(leftNavElement);
                }
            });
        },
        
        /** 处理导航栏尺寸变化 */
        handleNavResize() {
            // 刷新CodeMirror编辑器布局
            if (this.$refs.codeMirrorEditorRef && this.$refs.codeMirrorEditorRef.currentEditor) {
                // 延迟一点确保DOM更新完成
                this.$nextTick(() => {
                    this.$refs.codeMirrorEditorRef.currentEditor.refresh();
                    // 重新计算滚动比例
                    setTimeout(() => {
                        this.getScrollRatio();
                    }, 50);
                });
            }
        },
    }
};
</script>

<style scoped lang="less">
.home-content {
    padding-top: 40px;
    box-sizing: border-box;
    width: 100%;
    height: 100vh;
    display: flex;
    flex-wrap: wrap;
}

.left-nav {
    height: 100%;
    display: flex;

    .nav-wrap {
        width: 40px;
        height: 100%;
        padding: 8px 5px;
        box-sizing: border-box;
        position: relative;
    }

    .nav-item {
        width: 30px;
        height: 30px;
        text-align: center;
        line-height: 30px;
        cursor: pointer;
        border-radius: 4px;
        transition: all 0.2s;
        margin-bottom: 8px;

        &:last-child {
            margin: 0;
        }

        &:hover {
            background-color: rgba(136, 136, 136, 0.15);
        }

        &.focus {
            background-color: #409eff;
            color: #fff;
        }
    }

    .nav-item-bottom {
        position: absolute;
        bottom: 8px;
    }

    .iconfont {
        font-size: 20px;
    }

    .control-wrap {
        width: 240px;
        height: 100%;
        border-left: 1px solid #ddd;

        .control-file,
        .control-change {
            width: 100%;
            height: 100%;
            overflow: auto;
        }
    }
}

.left-word {
    width: 50%;
    height: 100%;
    flex: 1;
    background-color: #F5F5F5;
    box-sizing: border-box;
    overflow: auto;
}

.right-view {
    width: 50%;
    height: 100%;
    flex: 1;
    background-color: #fff;
    border-left: 1px solid #ddd;
    padding: 20px;
    box-sizing: border-box;
    overflow: auto;
}

.home-foot-version {
    position: fixed;
    bottom: 2px;
    right: 2px;
    color: #ddd;
    font-size: 14px;
}
</style>